//		Written by Todd Thomas Copyright (c) 1995 by Todd Thomas.
//				Version 1.0.  All rights reserved.
//
//		This notice may not be removed from this source code.
//
//	This object is included in the MiscKit by permission from the author
//	and its use is governed by the MiscKit license, found in the file
//	"LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
//	for a list of all applicable permissions and restrictions.
//	

#import <appkit/appkit.h>
#import <misckit/MiscTime.h>
#import <misckit/MiscClockView.h>
#import <misckit/MiscClockView_MiscTime.h>
#import <misckit/MiscFile.h>
#import <misckit/MiscUser.h>
#import <misckit/MiscUserGroup.h>
#import "FileInspector.h"


@implementation FileInspector

- selectedFile: (MiscFile *)theFile
{
	// There is a selected file to inspect. Get all of it's relevant
	// information and display in the inspector.
	char  tmp[20];
	int  fsize;
	MiscTime  *changeTime;
	MiscFile  *linkSource;
	MiscUser  *fileOwner;
	MiscUserGroup  *fileGroup;
	unsigned short  perms;
	
	if (theFile == nil)
		return self;
	
	// If permissions are changed, then we need to know which file.
	fileSelected = theFile;

	// Turn off stat caching so we get the most up to date information.
	[theFile setEnableCaching: NO];	
	fsize = [theFile size];
	// Turn on caching so all the calls below don't stat the file again.
	[theFile setEnableCaching: YES];
		
	[filename setStringValue: [theFile filename] ];
	[path setStringValue: [theFile fullPath] ];
	if ([theFile isSymbolicLink])
	{
		[linktoTitle setTextGray: NX_BLACK];
		linkSource = [theFile symbolicLinkSource];
		[linkto setStringValue: [linkSource fullPath] ];
		linkSource = [linkSource free];
	 }
	else
	{
		[linkto setStringValue: ""];
		[linktoTitle setTextGray: NX_DKGRAY];
	 } 
	 
	if (fsize < 1024*100)
		sprintf (tmp, "%d bytes", fsize);
	else
		sprintf (tmp, "%2.3f MB", (float)fsize/(1024*1024));
	[size setStringValue: tmp];
	
	[imageView setImage: [theFile iconImage] ];
	changeTime = [theFile lastModifyTime];
	[clock setMiscTime: changeTime];
	[changeTime free];
	
	perms = [theFile permissions];
	[ [permissionMatrix cellAt: 2 : 2] setState: (perms & 0x0001)];
	[ [permissionMatrix cellAt: 1 : 2] setState: (perms & 0x0002)];
	[ [permissionMatrix cellAt: 0 : 2] setState: (perms & 0x0004)];

	[ [permissionMatrix cellAt: 2 : 1] setState: (perms & 0x0008)];
	[ [permissionMatrix cellAt: 1 : 1] setState: (perms & 0x0010)];
	[ [permissionMatrix cellAt: 0 : 1] setState: (perms & 0x0020)];

	[ [permissionMatrix cellAt: 2 : 0] setState: (perms & 0x0040)];
	[ [permissionMatrix cellAt: 1 : 0] setState: (perms & 0x0080)];
	[ [permissionMatrix cellAt: 0 : 0] setState: (perms & 0x0100)];
	[permissionMatrix display];
	
	fileOwner = [theFile owner];
	[owner setStringValue: [fileOwner username] ];
	[fileOwner free];
	
	fileGroup = [theFile group];
	[group setStringValue: [fileGroup groupName] ];
	[fileGroup free];
	
	return self;
}


- permissionsChanged: sender
{
	// Activated when one of the permissions radio buttons is changed.
	// We should then try to change the permissions for the selected
	// file.
	int  selectedCol = [sender selectedCol];
	int  selectedRow = [sender selectedRow];
	int  state = [ [sender selectedCell] state];
	int  permToChange = 0;
	int  who = 0;
	int  succ;
	
	// If somehow this gets called with no file selected, quit.
	if (fileSelected == nil)	
		return self;
		
	switch (selectedCol)
	{
		case 0:	who = MISCFILE_OWNER; break;
		case 1: who = MISCFILE_GROUP; break;
		case 2: who = MISCFILE_OTHER; break;
	 }
	
	switch (selectedRow)
	{
		case 0: permToChange = MISCFILE_READ; break;
		case 1: permToChange = MISCFILE_WRITE; break;
		case 2: permToChange = MISCFILE_EXECUTE; break;
	 }
	
	if (state == 0)
		// Was 1, so removing a permission.
		succ = [fileSelected removePermissions: permToChange for: who];
	else
		// Was 0, now 1, so adding a permission.
		succ = [fileSelected addPermissions: permToChange for: who];
		
	if (succ == MISCFILE_ERROR)
	{
		// The change was not allowed, so update the matrix to reflect that.
		[ [sender selectedCell] setState: !(state)];
		[sender display];
	 }
	
	return self;
}

	
- window
{
	// The inspector window, so when loaded, we can tell it to show itself.
	return inspectorWin;
}

@end


@implementation FileInspector (NibInitialization)

- awakeFromNib
{
	// Setup the MiscClippedTextFields.
	[path setBordered: NO];
	[path setBackgroundGray: NX_LTGRAY];
	[linkto setBordered: NO];
	[linkto setBackgroundGray: NX_LTGRAY];
	return self;
}

@end
